package com.shm.leetcode;

/**
 * 83. 删除排序链表中的重复元素
 * 存在一个按升序排列的链表，给你这个链表的头节点 head ，请你删除所有重复的元素，使每个元素 只出现一次 。
 *
 * 返回同样按升序排列的结果链表。
 *
 *
 *
 * 示例 1：
 *
 *
 * 输入：head = [1,1,2]
 * 输出：[1,2]
 * 示例 2：
 *
 *
 * 输入：head = [1,1,2,3,3]
 * 输出：[1,2,3]
 *
 *
 * 提示：
 *
 * 链表中节点数目在范围 [0, 300] 内
 * -100 <= Node.val <= 100
 * 题目数据保证链表已经按升序排列
 *
 * @author SHM
 */
public class DeleteDuplicatesI {
    public ListNode deleteDuplicates(ListNode head) {
        if(head==null){
            return head;
        }
        ListNode pre = head;
        ListNode cur = pre.next;
        while(cur!=null){
            ListNode next = cur.next;
            if(pre.val==cur.val){
                pre.next = next;
                cur=next;
            }else{
                pre=cur;
                cur=next;
            }
        }

        return head;
    }

    /**
     * 方法一：一次遍历
     * 思路与算法
     *
     * 由于给定的链表是排好序的，因此重复的元素在链表中出现的位置是连续的，因此我们只需要对链表进行一次遍历，就可以删除重复的元素。
     *
     * 具体地，我们从指针 \textit{cur}cur 指向链表的头节点，随后开始对链表进行遍历。如果当前 \textit{cur}cur 与 \textit{cur.next}cur.next 对应的元素相同，那么我们就将 \textit{cur.next}cur.next 从链表中移除；否则说明链表中已经不存在其它与 \textit{cur}cur 对应的元素相同的节点，因此可以将 \textit{cur}cur 指向 \textit{cur.next}cur.next。
     *
     * 当遍历完整个链表之后，我们返回链表的头节点即可。
     *
     * 细节
     *
     * 当我们遍历到链表的最后一个节点时，\textit{cur.next}cur.next 为空节点，如果不加以判断，访问 \textit{cur.next}cur.next 对应的元素会产生运行错误。因此我们只需要遍历到链表的最后一个节点，而不需要遍历完整个链表。
     *
     * 复杂度分析
     *
     * 时间复杂度：O(n)O(n)，其中 nn 是链表的长度。
     *
     * 空间复杂度：O(1)O(1)。
     * 作者：LeetCode-Solution
     * 链接：https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list/solution/shan-chu-pai-xu-lian-biao-zhong-de-zhong-49v5/
     * @param head
     * @return
     */
    public ListNode deleteDuplicates_2(ListNode head) {
        ListNode cur=head;
        while (cur!=null&&cur.next!=null){
            if(cur.val==cur.next.val){
                cur.next = cur.next.next;
            }else{
                cur=cur.next;
            }
        }
        return head;
    }
}
